using System;
using System.Collections.Generic;
using System.Windows.Forms;

using Utilities;

namespace GPX
{
    public partial class MainFrame : FormEx
    {
        #region Variables
        private string _FileName;
        private GPXType _GPX;
        #endregion

        private System.Resources.ResourceManager ResourceManager
        {
            get { return GPXAppResourceManager.ResourceManager; }
        }

        public MainFrame()
        {
            InitializeComponent();
            if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Runtime)
            {
                Localizer.SetCulture();
                Localizer.LocalizeControl(this, ResourceManager);
            }
        }

        private void menuFileOpen_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog ofd = new OpenFileDialog();
                //GPX_MainFrame_menuFileOpen_Click0=GPX-Files (*.gpx)|*.gpx
                ofd.Filter = ResourceManager.GetString("GPX_MainFrame_menuFileOpen_Click0");
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    OpenFile(ofd.FileName);
                }
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        internal void OpenFile(string fileName)
        {
            _FileName = fileName;

            //TODO: determine the version of the GPX file
            try
            {
                _GPX = GPXType.FromFile(_FileName);
            }
            catch (InvalidOperationException)
            {
                //Version 1.0
                GPX_1_0.gpx oldData = GPX_1_0.gpx.FromFile(fileName);
                _GPX = GPXType.FromVersion_1_0(oldData);
            }
            WayPoint.SetSpeedUnitFactor(Defaults.GPX_SpeedUnitFactor);
            ShowData();
            if (Defaults.AutoViewTrack)
                ShowTrack();

        }

        private void menuFileSave_Click(object sender, EventArgs e)
        {
            try
            {
                UpdateData();
                SaveData();
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void menuFileSaveAs_Click(object sender, EventArgs e)
        {
            try
            {
                UpdateData();
                SaveFileDialog sfd = new SaveFileDialog();
                //GPX_MainFrame_menuFileOpen_Click0=GPX-Files (*.gpx)|*.gpx
                sfd.Filter = ResourceManager.GetString("GPX_MainFrame_menuFileOpen_Click0");
                sfd.FileName = _FileName;
                sfd.InitialDirectory = System.IO.Path.GetDirectoryName(_FileName);
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    _FileName = sfd.FileName;
                    SaveData();
                }
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void SaveData()
        {
            _GPX.ToFile(_FileName);
        }

        private void menuFileExit_Click(object sender, EventArgs e)
        {
            try
            {
                Application.Exit();
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void menuViewTrack_Click(object sender, EventArgs e)
        {
            ShowTrack();
        }

        private void ShowTrack()
        {
            try
            {
                if (_GPX == null)
                {
                    //GPX_MainFrame_menuFileOpen_Click0=You must load a GPX file first
                    string msg = ResourceManager.GetString("GPX_MainFrame_menuFileExportHeartRate_Click0");
                    MessageBox.Show(msg, null, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                MapForm map = new MapForm(_GPX.Tracks[(int)nudSelectedTrack.Value].TrackSegments[(int)nudSelectedSegment.Value]);
                map.PointsOfInterest = _GPX.WayPoints;
                map.Show();
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void ShowData()
        {
            ClearUI();
            txtFileName.Text = _FileName;

            menuEditConvertRoute.Enabled = (_GPX.Routes != null && _GPX.Routes.Count > 0);

            if (_GPX.Tracks == null)
            {
                txtNoTracks.Text = "0";
                return;
            }

            txtNoTracks.Text = _GPX.Tracks.Count.ToString();
            //the rest is dealt with in the event handler of the numeric up-down
            if (_GPX.Tracks.Count == 0)
            {
                nudSelectedTrack.Enabled = false;
            }
            else
            {
                nudSelectedTrack.Enabled = true;
                if (nudSelectedTrack.Value == 0)
                {
                    //not nice...
                    nudSelectedTrack_ValueChanged(null, null);
                }
                else
                {
                    nudSelectedTrack.Value = 0;
                }
                nudSelectedTrack.Maximum = _GPX.Tracks.Count - 1;
            }
        }

        private void ClearUI()
        {
            txtFileName.Text = string.Empty;
            txtNoTracks.Text = string.Empty;
            txtTrack1Name.Text = string.Empty;
            txtNoSegments.Text = string.Empty;
            txtLength.Text = string.Empty;
            txtDuration.Text = string.Empty;
            txtLongMin.Text = string.Empty;
            txtLatMin.Text = string.Empty;
            txtEleMin.Text = string.Empty;
            txtCountWayPoint.Text = string.Empty;
            txtMaxSpeed.Text = string.Empty;
            txtLongMax.Text = string.Empty;
            txtLatMax.Text = string.Empty;
            txtEleMax.Text = string.Empty;
        }

        private void UpdateData()
        {
            //change Name of Track
            Track track = _GPX.Tracks[(int)nudSelectedTrack.Value];
            track.Name = txtTrack1Name.Text.Trim();
        }

        private void nudSelectedTrack_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                Track track = _GPX.Tracks[(int)nudSelectedTrack.Value];
                track.Recalculate();
                txtTrack1Name.Text = track.Name;
                txtNoSegments.Text = track.TrackSegments.Count.ToString();
                if (track.TrackSegments.Count == 0)
                {
                    nudSelectedSegment.Enabled = false;
                }
                else
                {
                    nudSelectedSegment.Enabled = true;
                    if (nudSelectedSegment.Value == 0)
                    {
                        //not nice...
                        nudSelectedSegment_ValueChanged(null, null);
                    }
                    else
                    {
                        nudSelectedSegment.Value = 0;
                    }
                    nudSelectedSegment.Maximum = track.TrackSegments.Count - 1;
                }
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void nudSelectedSegment_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                TrackSegment segment = _GPX.Tracks[(int)nudSelectedTrack.Value].TrackSegments[(int)nudSelectedSegment.Value];
                txtCountWayPoint.Text = segment.WayPoints.Count.ToString();
                txtLength.Text = (segment.GetSegmentLength() / 1000).ToString("F3") + " km";
                TimeSpan x = segment.GetDuration();
                txtDuration.Text = segment.GetDuration().ToString(); //"HH:mm:ss"
                txtMaxSpeed.Text = segment.GetMaximumSpeed().ToString("F1"); // +" km/h";
                txtLatMin.Text = segment.TrackBounds.LatitudeMinimum.ToString();
                txtLatMax.Text = segment.TrackBounds.LatitudeMaximum.ToString();
                txtLongMin.Text = segment.TrackBounds.LongitudeMinimum.ToString();
                txtLongMax.Text = segment.TrackBounds.LongitudeMaximum.ToString();
                txtEleMin.Text = segment.TrackBounds.ElevationMinimum.ToString("F1") + " m";
                txtEleMax.Text = segment.TrackBounds.ElevationMaximum.ToString("F1") + " m";
                txtTotalAscent.Text = segment.TotalAscent.ToString("F1") + " m";
                txtTotalDescent.Text = segment.TotalDescent.ToString("F1") + " m";
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void menuEditGMap_Click(object sender, EventArgs e)
        {
            try
            {
                GMapDialog gMapDlg = new GMapDialog(_GPX.Tracks[(int)nudSelectedTrack.Value].TrackSegments[(int)nudSelectedSegment.Value]);
                gMapDlg.ShowDialog();
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void menuHelpAbout_Click(object sender, EventArgs e)
        {
            try
            {
                AboutForm about = new AboutForm();
                about.ShowDialog();
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void MainFrame_DragEnter(object sender, DragEventArgs e)
        {
            try
            {
                DragDropEffects effect = DragDropEffects.None;
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                    if (files.GetLength(0) == 1 && (System.IO.Path.GetExtension(files[0]).ToLower() == ".gpx"))
                    {
                        effect = DragDropEffects.Copy;
                    }
                }
                e.Effect = effect;
            }
            catch
            {
                //swallow
            }
        }

        private void MainFrame_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                    if (files.GetLength(0) == 1 && (System.IO.Path.GetExtension(files[0]).ToLower() == ".gpx"))
                    {
                        OpenFile(files[0]);
                    }
                }
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void menuHelpManual_Click(object sender, EventArgs e)
        {
            try
            {

            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void menuEditConvertRoute_Click(object sender, EventArgs e)
        {
            try
            {
                int selectedIndex = 0;
                //TODO: Request user to select route
                if (_GPX.Routes.Count > 1)
                {
                }
                Route route = _GPX.Routes[selectedIndex];
                Track track = Track.FromRoute(route);
                if (_GPX.Tracks == null)
                    _GPX.Tracks = new List<Track>();
                _GPX.Tracks.Add(track);
                ShowData();
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }

        private void menuFileExportHeartRate_Click(object sender, EventArgs e)
        {
            try
            {
                if (_GPX == null)
                {
                    //GPX_MainFrame_menuFileOpen_Click0=You must load a GPX file first
                    string msg = ResourceManager.GetString("GPX_MainFrame_menuFileExportHeartRate_Click0");
                    MessageBox.Show(msg, null, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                SaveFileDialog sfd = new SaveFileDialog();
                string filename = string.Format("Heartrate_{0:yyyyMMdd}.ges", DateTime.Today);
                sfd.FileName = filename;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    _GPX.ExportHeartrate(sfd.FileName);
                }
            }
            catch (Exception ex)
            {
                Utils.HandleException(ex);
            }
        }
    }
}
